package com.idea.relax.log.publisher;


import com.idea.relax.log.constant.ErrorLogConstant;
import com.idea.relax.log.event.ErrorLogEvent;
import com.idea.relax.log.model.ErrorLogModel;
import com.idea.relax.log.support.MethodExecuteResult;
import com.idea.relax.log.support.AppInfoProvider;
import com.idea.relax.log.support.RequestMetadata;
import com.idea.relax.log.support.utils.WebUtil;
import lombok.AllArgsConstructor;
import org.springframework.context.ApplicationEvent;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * @className: ErrorLogPublisher
 * @description: 错误日志事件发布者
 * @author: salad
 * @date: 2022/6/3
 **/
@AllArgsConstructor
public class ErrorLogPublisher implements ILogPublisher {

    private final ApplicationEvent event;

    public static ErrorLogPublisher build(MethodExecuteResult methodExecuteResult,
                                          HttpServletRequest request) {
        ErrorLogModel model = new ErrorLogModel();
        AppInfoProvider.appendRequestInfo(request, model);
        model.setStatus(methodExecuteResult.getResponseStatus().getState());
        model.setTime(methodExecuteResult.getTime());
        Wrapper<Map<String, Object>> wrapper = getWrapper(model, methodExecuteResult);
        return new ErrorLogPublisher(new ErrorLogEvent(wrapper));
    }

    public static ErrorLogPublisher build(MethodExecuteResult methodExecuteResult,
                                          RequestMetadata rmd) {
        ErrorLogModel model = new ErrorLogModel();
        model.setRequestTime(rmd.getRequestTime());
        model.setVisitorIp(rmd.getVisitorIp());
        model.setRequestUri(rmd.getRequestUri());
        model.setRequestMethod(rmd.getRequestMethod());
        model.setRequestParams(rmd.getRequestParams());
        model.setUserAgent(rmd.getUserAgent());
        model.setStatus(methodExecuteResult.getResponseStatus().getState());
        model.setTime(methodExecuteResult.getTime());
        Wrapper<Map<String, Object>> wrapper = getWrapper(model, methodExecuteResult);
        return new ErrorLogPublisher(new ErrorLogEvent(wrapper));
    }

    public static ErrorLogPublisher build(MethodExecuteResult methodExecuteResult) {
        ErrorLogModel model = new ErrorLogModel();
        AppInfoProvider.appendRequestInfo(WebUtil.getRequest(), model);
        model.setStatus(methodExecuteResult.getResponseStatus().getState());
        model.setTime(methodExecuteResult.getTime());
        Wrapper<Map<String, Object>> wrapper = getWrapper(model, methodExecuteResult);
        return new ErrorLogPublisher(new ErrorLogEvent(wrapper));
    }

    public static Wrapper<Map<String, Object>> getWrapper(ErrorLogModel model, MethodExecuteResult methodExecuteResult) {
        Map<String, Object> values = new HashMap<>(16);
        values.put(ErrorLogConstant.ERR_LOG_MODEL, model);
        values.put(ErrorLogConstant.ERROR, methodExecuteResult.getEx());
        return new Wrapper<>(values);
    }

    @Override
    public void publish() {
        LogEventPublisher.publish(event);
    }


}
